package com.jgit;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import java.io.ByteArrayInputStream;

/**
 * Git对象的基类
 * Git使用SHA-1哈希来标识对象，并压缩存储
 */
public abstract class GitObject {
    protected String hash;
    protected byte[] content;
    
    public GitObject() {
    }
    
    /**
     * 获取对象的类型（blob, tree, commit）
     */
    public abstract String getType();
    
    /**
     * 获取对象的原始内容（未压缩）
     */
    public abstract byte[] getRawContent() throws IOException;
    
    /**
     * 计算对象的SHA-1哈希值
     */
    public String calculateHash() throws IOException {
        try {
            byte[] rawContent = getRawContent();
            String header = getType() + " " + rawContent.length + "\0";
            byte[] headerBytes = header.getBytes();
            
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(headerBytes);
            digest.update(rawContent);
            
            byte[] hashBytes = digest.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
            }
            this.hash = sb.toString();
            return this.hash;
        } catch (NoSuchAlgorithmException e) {
            throw new IOException("SHA-1 algorithm not found", e);
        }
    }
    
    /**
     * 获取对象的哈希值
     */
    public String getHash() {
        return hash;
    }
    
    /**
     * 压缩对象内容（使用zlib）
     */
    public byte[] compress() throws IOException {
        byte[] rawContent = getRawContent();
        String header = getType() + " " + rawContent.length + "\0";
        byte[] headerBytes = header.getBytes();
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DeflaterOutputStream dos = new DeflaterOutputStream(baos, new Deflater(Deflater.DEFAULT_COMPRESSION));
        dos.write(headerBytes);
        dos.write(rawContent);
        dos.finish();
        dos.close();
        
        return baos.toByteArray();
    }
    
    /**
     * 从压缩数据解压对象
     */
    public static GitObject decompress(byte[] compressedData) throws IOException {
        ByteArrayInputStream bais = new ByteArrayInputStream(compressedData);
        InflaterInputStream iis = new InflaterInputStream(bais);
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = iis.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        iis.close();
        
        byte[] decompressed = baos.toByteArray();
        
        // 解析头部
        int nullIndex = -1;
        for (int i = 0; i < decompressed.length; i++) {
            if (decompressed[i] == 0) {
                nullIndex = i;
                break;
            }
        }
        
        if (nullIndex == -1) {
            throw new IOException("Invalid git object format");
        }
        
        String header = new String(decompressed, 0, nullIndex);
        String[] parts = header.split(" ");
        String type = parts[0];
        int contentLength = Integer.parseInt(parts[1]);
        
        byte[] content = new byte[contentLength];
        System.arraycopy(decompressed, nullIndex + 1, content, 0, contentLength);
        
        // 根据类型创建相应的对象
        switch (type) {
            case "blob":
                return Blob.fromContent(content);
            case "tree":
                return Tree.fromContent(content);
            case "commit":
                return Commit.fromContent(content);
            default:
                throw new IOException("Unknown object type: " + type);
        }
    }
}

